home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <string.h>
- #include <unistd.h>
- #include <fcntl.h>
-
- #include <sys/wait.h>
-
- #define VERSION "VH1.20"
-
- #ifndef TTY
- #define TTY "/dev/tty1"
- #endif
-
- #ifndef SHELL
- #define SHELL "/bin/sh"
- #endif
-
- #ifndef SASH
- #define SASH "/sbin/sash:/bin/sash:/etc/sash"
- #endif
-
- #ifndef INIT
- #define INIT "/bin/init:/sbin/init"
- #endif
-
- static void
- put(const char *s)
- {
- static int in_line=0;
-
- for (; *s; putc(*s++, stderr))
- if (*s=='\n')
- {
- putc('\r', stderr);
- in_line = 0;
- }
- else if (!in_line)
- {
- in_line = 1;
- put("failinit " VERSION ": ");
- }
- }
-
- static void
- start(const char *shells, char * const *argv)
- {
- char name[100];
- const char *ptr;
-
- for (ptr=shells;;)
- {
- int i;
-
- for (i=0; i<sizeof name-1 && *ptr; i++)
- if ((name[i]= *ptr++)==':')
- break;
- if (!i)
- break;
- name[i] = 0;
- if (argv)
- execv(name, argv);
- else
- {
- while (--i>=0 && name[i-1]!='/');
- execl(name, name+i, NULL);
- }
- }
- perror(shells);
- }
-
- static int
- shell(const char *tty)
- {
- if (tty)
- {
- close(0);
- close(1);
- close(2);
- setsid();
- if (open(tty,O_RDWR,0))
- {
- perror(tty);
- exit(-2);
- }
- dup(0);
- dup(0);
- }
- start(SASH, NULL);
- start(SHELL, NULL);
- exit(-1);
- }
-
- static void
- waiter(int pid)
- {
- do
- sync();
- while (wait(NULL)!=pid);
- sync();
- }
-
- static void
- fail_shell(int stop)
- {
- int i;
-
- put("\nforking fail shell ");
- put(stop ? "to " TTY : "in background");
- put(" ...\n");
- if ((i=fork())==0)
- shell(stop ? TTY : NULL);
- if (stop && i>=0)
- {
- waiter(i);
- put("\nfail shell terminated, proceeding with normal startup ...\n");
- }
- }
-
- static void
- emergency_shell(void)
- {
- int i, fail;
-
- put("\ninit not found ... spawning emergency shell (like in 1.1.82)\n");
- fail = 0;
- for (;;)
- if ((i=fork())==0)
- shell(TTY);
- else if (i<0)
- {
- if (!fail)
- put("cannot fork() !!! sleeping ...\n");
- fail = 1;
- sleep(1);
- }
- else
- {
- if (fail)
- put("OK, fork() is back again\n");
- fail = 0;
- waiter(i);
- put("emergency shell terminated.\n");
- sleep(1);
- }
- }
-
- int
- main(int argc, char **argv)
- {
- int i;
-
- if (argv[1] && !strncmp(argv[1], "fail", 4))
- {
- fail_shell(argv[1][4]);
- for (i=1; (argv[i]=argv[i+1])!=0; i++);
- }
- if (argv[1])
- {
- put("\narguments passed to init:\n");
- for (i=1; argv[i]; i++)
- {
- put("\t\'");
- put(argv[i]);
- put("\'\n");
- }
- put("\n");
- }
- start(INIT, argv);
- emergency_shell();
- return -1;
- }
-